home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / diskutil / noahdi.zoo / noahdi / hd_extra.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  14KB  |  377 lines

  1. /*
  2.     File: HD_EXTRA.C     Extra Low Level Harddisk Routines.
  3. */
  4. /*
  5. Copyright (c) 1988 - 1991 by Ted Schipper.
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation.
  12.  
  13. This software is provided AS IS with no warranties of any kind.  The author
  14. shall have no liability with respect to the infringement of copyrights,
  15. trade secrets or any patents by this file or any part thereof.  In no
  16. event will the author be liable for any lost revenue or profits or
  17. other special, indirect and consequential damages.
  18. */
  19.  
  20. #include "dma.h"
  21. #include "mfp.h"
  22. #include "hddriver.h"
  23. #include "system.h"
  24.  
  25. /***************************************************************************
  26.  
  27.                         Some EXTRA LOW-LEVEL Stuff
  28.                        ----------------------------
  29.  HISTORY
  30. ---------
  31.  Nov 1988. THS. Started. Tested send_cmd routine. Added req_sense.
  32.  Dec 1988. THS. Tested req_sense routine. Not sure it works OK. HAC bug.
  33.  Jan 1989. THS. Added, tested wd_msel and wd_format. Also tested some
  34.                 drive errors. Controller always reports no errors.
  35.                 V0.00
  36.  
  37. ***************************************************************************/
  38.  
  39. /***************************************************************************
  40.  *
  41.  * Function name : wd_format. Format hard disk
  42.  * Parameters    : short  device number. 4 bits: bit 0   = drive # ( 0 or 1)
  43.  *                                               bit 1-3 = controller # (0-7)
  44.  *                 short  pattern_flag.  2 bits: bit 1-3 = Data pattern Flag
  45.  *                 short  pattern.       8 bits: bit 0-7 = Data pattern
  46.  *                 short  ileave_high.   8 bits: bit 0-7 = Interleave High
  47.  *                 short  ileave_low.    8 bits: bit 0-7 = Interleave Low
  48.  * Returns       : long. dma completion byte or time-out (-1)
  49.  * Description   : Format a harddisk with given pattern and interleave.
  50.  * Comments      : Assumes processor is in supervisor mode, and drive
  51.  *                 specifications has been set with the wd_msel command.
  52.  */
  53.  
  54. long wd_format(dev,pattern_flag,pattern,ileave_high,ileave_low)
  55.  
  56.  short dev;
  57.  short pattern_flag;
  58.  short pattern;
  59.  short ileave_high;
  60.  short ileave_low;
  61.  
  62. {
  63.  long status;
  64.  short dummy = 0;
  65.  
  66.  FLOCK = -1;                            /* disable FDC operations */
  67.  DMA->MODE = NO_DMA | HDC;              /* write 1st byte (0) with A1 low */
  68.  DMA->DATA = (short)((dev >> 1) << 5) | (HD_FD); /* contrl# + command */
  69.  DMA->MODE = NO_DMA | HDC | A0;
  70.  if (qdone() != OK)                     /* wait for ack */
  71.  {
  72.     hdone();                            /* restore DMA device to normal */
  73.     return(ERROR);
  74.  }
  75.  DMA->DATA =  (short)((dev & 1) << 5) | (pattern_flag & 6); /* drv# + pat flag */
  76.  DMA->MODE = NO_DMA | HDC | A0;
  77.  if (qdone() != OK)                     /* wait for ack */
  78.  {
  79.     hdone();                            /* restore DMA device to normal */
  80.     return(ERROR);
  81.  }
  82.  DMA->DATA = pattern;
  83.  DMA->MODE = NO_DMA | HDC | A0;
  84.  if (qdone() != OK)                     /* wait for ack */
  85.  {
  86.     hdone();                            /* restore DMA device to normal */
  87.     return(ERROR);
  88.  }
  89.  DMA->DATA = ileave_high;
  90.  DMA->MODE = NO_DMA | HDC | A0;
  91.  if (qdone() != OK)                     /* wait for ack */
  92.  {
  93.     hdone();                            /* restore DMA device to normal */
  94.     return(ERROR);
  95.  }
  96.  DMA->DATA = ileave_low;
  97.  DMA->MODE = NO_DMA | HDC | A0;
  98.  if (qdone() != OK)                     /* wait for ack */
  99.  {
  100.     hdone();                            /* restore DMA device to normal */
  101.     return(ERROR);
  102.  }
  103.  DMA->DATA = dummy;
  104.  DMA->MODE = NO_DMA | HDC | A0;
  105.  
  106.  while ((MFP->GPIP & IO_DINT) == IO_DINT) ; /* wait (forever) for completion */
  107.  status = (long)(DMA->DATA & 0x00FF);   /* get the status */
  108.  hdone();                               /* restore DMA device to normal */
  109.  return(status);                        /* return completion status */
  110. }
  111.  
  112.  
  113. /***************************************************************************
  114.  *
  115.  * Function name : wd_msel. Mode select. Specify drive format parameters.
  116.  * Parameters    : short device number. 4 bits: bit 0   = drive # ( 0 or 1 )
  117.  *                                              bit 1-3 = controller # (0-7)
  118.  *                 short count.         size of parameter block.
  119.  *                 char * parameterblock. pointer to parameter block.
  120.  * Returns       : long. ASCI completion byte or time-out.
  121.  * Description   : Send a mode select command to a controller and drive
  122.  *                 followed by the parameter block which is send under DMA.
  123.  * Comments      : Assumes processor is in supervisor mode, and parameter
  124.  *                 block is not bigger than 1 sector (512 bytes).
  125.  */
  126.  
  127. long wd_msel(dev,cnt,param)
  128.  
  129.  short dev;
  130.  short cnt;
  131.  char * param;
  132.  
  133. {
  134.  long status;
  135.  short dummy = 0;
  136.  
  137.  FLOCK = -1;                            /* disable FDC operations */
  138.  setdma(param);                         /* setup DMA transfer address */
  139.  DMA->MODE = NO_DMA | HDC;              /* write 1st byte (0) with A1 low */
  140.  DMA->DATA = (short)((dev >> 1) << 5) | (HD_MSEL); /* contrl# + command */
  141.  DMA->MODE = NO_DMA | HDC | A0;
  142.  if (qdone() != OK)                     /* wait for ack */
  143.  {
  144.     hdone();                            /* restore DMA device to normal */
  145.     return(ERROR);
  146.  }
  147.  DMA->DATA =  (short)((dev & 1) << 5);  /* drv# */
  148.  DMA->MODE = NO_DMA | HDC | A0;
  149.  if (qdone() != OK)                     /* wait for ack */
  150.  {
  151.     hdone();                            /* restore DMA device to normal */
  152.     return(ERROR);
  153.  }
  154.  DMA->DATA = dummy;
  155.  DMA->MODE = NO_DMA | HDC | A0;
  156.  if (qdone() != OK)                     /* wait for ack */
  157.  {
  158.     hdone();                            /* restore DMA device to normal */
  159.     return(ERROR);
  160.  }
  161.  DMA->DATA = dummy;
  162.  DMA->MODE = NO_DMA | HDC | A0;
  163.  if (qdone() != OK)                     /* wait for ack */
  164.  {
  165.     hdone();                            /* restore DMA device to normal */
  166.     return(ERROR);
  167.  }
  168.  DMA->DATA = cnt;
  169.  DMA->MODE = NO_DMA | HDC | A0;
  170.  if (qdone() != OK)                     /* wait for ack */
  171.  {
  172.     hdone();                            /* restore DMA device to normal */
  173.     return(ERROR);
  174.  }
  175.  DMA->MODE = NO_DMA | SC_REG;           /* clear FIFO and */
  176.  DMA->MODE = DMA_WR | NO_DMA | SC_REG;  /* select sector count register */
  177.  DMA->SECT_CNT = 1;                     /* sector count */
  178.  DMA->MODE = DMA_WR | NO_DMA | HDC | A0; /* select DMA register again */
  179.  DMA->DATA = dummy;                     /* write last byte */
  180.  DMA->MODE = DMA_WR;                    /* start DMA transfer */
  181.  if (fdone() != OK)                     /* wait for DMA completion */
  182.  {
  183.      hdone();                           /* restore DMA device to normal */
  184.      return(ERROR);
  185.  }
  186.  DMA->MODE = DMA_WR | NO_DMA | HDC | A0; /* set DMA register to normal */
  187.  status = (long)(DMA->DATA & 0x00FF);   /* get ASCI completion byte */
  188.  hdone();                               /* restore DMA device to normal */
  189.  return(status);                        /* return ASCI completion byte */
  190. }
  191.  
  192.  
  193. /***************************************************************************
  194.  *
  195.  * Function name : dosahdxc. Send an ASCI command with timeout.
  196.  * Parameters    : short device number. 4 bits: bit 0   = drive # ( 0 or 1 )
  197.  *                                              bit 1-3 = controller # (0-7)
  198.  *               : short * cdb. Pointer to the Command Descriptor Block.
  199.  * Returns       : long OK    = command block send OK.
  200.  *                      ERROR = timeout.
  201.  * Description   : Send 6 bytes from the Command Descriptor Block to an
  202.  *                 ASCI device.  
  203.  * Comments      : Assumes processor is in supervisor mode. 
  204.  */
  205.  
  206. long dodahdxc(dev,cdb)
  207.  
  208.  short dev;
  209.  short cdb[6];
  210.  
  211. {
  212.  short i;
  213.  long status;
  214.  
  215.  cdb[0] |= ((dev >> 1) << 5);           /* put controller# in first byte */
  216.  cdb[1] |= ((dev & 1) << 5);            /* put drive# in second byte */
  217.  FLOCK = -1;                            /* disable FDC operations */
  218.  DMA->